/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iiiexamenservidor;

/**
 *
 * Autora Ileana Natalia Díaz Palacios
 * Programación III
 * Universidad Nacional
 *
 * Creado el 26/11/2011
 * 02:42:33 PM
 *
 */
import basicprotocol.BasicProtocol;
import basicprotocol.SimpleMessage;
import control.Controladora;
import java.util.*;
import java.io.IOException;
import javax.swing.*;
import java.net.*;
import modelo.cliente;
public class IIIExamenServidor extends Observable implements Runnable{

     public IIIExamenServidor() {
         controladora = Controladora.instance();
    }

    public static void main(String args[]) {
        IIIExamenServidor server = new IIIExamenServidor();
        server.init();
    }

    public void init() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            JFrame.setDefaultLookAndFeelDecorated(true);
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        createAndShowGUI();
        mainWindow.showStatus("Iniciando servidor..");
        startServer();
    }

    public void startServer() {
        serverThread = new Thread(this);
        if (serverThread != null) {
            serverThread.start();
        }
    }

    @Override
    public void run() {

        try {
            // open();
        } catch (Exception e) {
            System.out.println("Ocurri\u00F3 un error al iniciar el servidor..");
        }

        while (!serverDone) {
            if (isActive()) {

                try {
                    Socket skt = null;

                    boolean done = false;
                    while (!done && isActive()) {
                        try {

                            srvr.setSoTimeout(1000);
                            mainWindow.showStatus("Esperando conexi\u00F3n..");
                            skt = srvr.accept();
                            String evt = String.format(
                                    "Conexi\u00F3n establecida desde %s", skt.getInetAddress());
                            mainWindow.showStatus(evt);
                            mainWindow.addToLog(evt);

                            SimpleMessage msg = SimpleMessage.receive(skt);
                            mainWindow.addToLog(String.format("Recibido: %s", msg));
                            System.out.println(msg.getCommand());
                            switch (msg.getCommand()) {
                                case BasicProtocol.STOP_MSG: {
                                    // close();
                                    done = true;
                                    break;
                                }
                                case BasicProtocol.INSERT_CLIENTE:
                                {
                                    cliente c = (cliente)msg.getMessage();
                                    controladora.agregarCliente(c);
                                     mainWindow.addToLog(String.format("Articulo insertado: %s", msg));
                                     break;
                                }
                                default: {
                                }
                            }

                            SimpleMessage ans = new SimpleMessage(
                                    BasicProtocol.ACK_MSG,
                                    getClass().getName(), null);
                            ans.send(skt);
                            skt.close();

                        } catch (SocketTimeoutException e) {
                            // mainWindow.showStatus("Tiempo de conexi\u00F3n expirado..");
                        } catch (SocketException e) {
                            done = true;
                        } catch (IOException e) {
                            e.printStackTrace(System.err);
                            done = true;
                        }
                        catch(Exception e)
                        {
                            System.out.println(e.toString());
                        }
                        finally {
                            if (skt != null) {
                                skt.close();
                                skt = null;
                            }
                        }
                    }
                    close();
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
            }
        }
        System.exit(0);
    }

    public synchronized void quitServer() {
        System.out.println("Cerrando servidor..");
        try {
            close();
        } catch (Exception e) {
        }
        serverDone = true;
    }

    public void createAndShowGUI() {
        mainWindow = new ServerWindow(this);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                mainWindow.init();
            }

        });
    }

    public int getServerPort() {
        return serverPort;
    }

    public void setServerPort(int newPort) {
        serverPort = newPort;
    }

    public synchronized boolean isActive() {
        return active;
    }

    public synchronized void setActive(boolean newState) {
        active = newState;
        setChanged();
        notifyObservers();
    }

    public synchronized void open(int newPort) throws IOException {
        System.out.println("Activando servidor..");
        setServerPort(newPort);
        srvr = new ServerSocket(serverPort);
        setActive(true);
    }

    public synchronized void close() throws IOException {
        System.out.println("Desactivando servidor..");
        srvr.close();
        setActive(false);
    }

    private int serverPort = BasicProtocol.DEFAULT_PORT;
    private boolean active = false;
    private ServerSocket srvr = null;
    private ServerWindow mainWindow = null;
    private Thread serverThread = null;
    private boolean serverDone = false;
    private Controladora controladora= null;
}
